package com.topscomm.mis.cbb.file.compare.word.util.aspose;

import com.aspose.words.Document;
import com.aspose.words.ImageSaveOptions;
import com.aspose.words.SaveFormat;
import com.aspose.words.SaveOutputParameters;
import com.topscomm.basic.exception.BusinessException;
import com.topscomm.basic.exception.ServiceException;
import com.topscomm.mis.cbb.file.compare.word.util.FileProcessProgressCache;
import com.topscomm.tap.common.ParameterCache;
import lombok.extern.slf4j.Slf4j;

import javax.imageio.ImageIO;
import javax.imageio.stream.ImageInputStream;
import javax.xml.transform.Source;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * 文件转图片
 *
 * @description:
 * @author: donghang
 * @date: 2021年3月16日下午2:12:06
 * @modify:
 */
@Slf4j
public class AsposeFileConvertToImg {
    private final static float imgResolution =150f;
    /**
     * @description: word文档转换成多个图片，默认图片格式为png
     * @author: liwanpeng
     * @date: 2023-02-23 09:53:24
     * @param: identifier 本次处理任务的唯一标识
     * @param: filePath 源文件路径
     * @param: targetPath 生成的文件路径
     * @param: isCreateAllPages 是否创建所有word页面的图片
     * @return: int
     * @modify:
     */
    private static int wordToMultipleImg(String identifier, String filePath, String targetPath, boolean isCreateAllPages)
            throws Exception {
        // 读取路径下的docx文件
        Document doc = new Document(filePath);
        // 页数
        int pageCount = 0;
        try {
            // 转换出的图片格式
            ImageSaveOptions options = new ImageSaveOptions(SaveFormat.PNG);
            // 设置图片分辨率
            options.setResolution(imgResolution);
            // 获取文档页数
            pageCount = doc.getPageCount();
            // 验证转换后的图片的路径是否存在，不存在则新建
            File targetFile = new File(targetPath);
            if (!targetFile.exists()) {
                targetFile.mkdir();
            }
            // 文档总页数大于0才开始进行转换
            if (pageCount > 0) {
                // 矫正文档转图片后总数量的差异，发现问题于2022.08.30，该word文档初始获取文档总页数为93页，转换后实际为92页，导致临界值超范围异常。
                options.setPageIndex(0);
                // 组装文件名（总页数_当前页数_.png）
                String imageFilePath = targetPath + "/" + "pagecount" + "_" + 0 + ".png";
                FileOutputStream fileOS = new FileOutputStream(imageFilePath);
                try {
                    doc.save(fileOS, options);
                } catch (Exception e) {
                    throw new ServiceException(e);
                } finally {
                    if (fileOS != null) {
                        fileOS.flush();
                        fileOS.close();
                    }
                }
                pageCount = doc.getPageCount();
            }
            String fileName = targetPath.substring(targetPath.lastIndexOf("/") + 1) + "_" + pageCount;
            if (isCreateAllPages == false) {
                int maxTitlePages = ParameterCache.getIntValue("FileMaxTitlePages", 6);
                pageCount = pageCount < maxTitlePages ? pageCount : maxTitlePages;
            }
            for (int i = 1; i <= pageCount; i++) {
                options.setPageIndex(i - 1);
                String imageFilePath = targetPath + "/" + fileName + "_" + i + ".png";
                FileOutputStream fileOS = new FileOutputStream(imageFilePath);
                try {
                    doc.save(fileOS, options);
                } catch (Exception e) {
                    throw new ServiceException(e);
                } finally {
                    if (fileOS != null) {
                        fileOS.flush();
                        fileOS.close();
                    }
                }
                // 更新处理进度
                if (isCreateAllPages == true) {
                    FileProcessProgressCache.putValue(identifier, pageCount, i, "");
                }
            }
        } catch (Exception e) {
            throw new ServiceException(e);
        } finally {
            if (doc != null) {
                doc.cleanup();
            }
        }
        return pageCount;
    }

    /**
     * @description: 将文档转换为一张图片
     * @author: liwanpeng
     * @date: 2023-02-24 19:54:43
     * @param: filePath
     * @return: java.lang.String
     * @modify:
     */
    public static String convertOneImg(String filePath){

        try {
            // 读取待转换的文件
            File file = new File(filePath);
            if (!file.isFile()){
                throw new BusinessException("不是一个文件。");
            }
            String fileName = file.getName();
            // 获取后缀
            int temp = fileName.lastIndexOf(".") + 1;
            String suffix = fileName.substring(temp);
            if (!suffix.equals("docx")){
                throw new BusinessException("仅支持docx文档转换成图片。");
            }
            InputStream inStream = new FileInputStream(file);
            // 生成文档对象
            Document doc = new Document(filePath);
            // 文档总页数
            int pageCount = doc.getPageCount();
            // 每个页对应一个图片缓存
            List<BufferedImage> wordToImg = wordToImg(inStream,pageCount+2);
            // 最终合成的图片的缓存
            BufferedImage mergeImage = mergeImage(false, wordToImg);
            // 合成后的图片保存路径，生成到当前目录下
            String imgPath = file.getParent()+"/"+fileName.replace(suffix,"")+".jpg";
            ImageIO.write(mergeImage, "jpg",new File( imgPath));
            try {
                inStream.close();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
            return imgPath;

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }


    /**
     * @description: word和txt文件转换图片
     * @author: liwanpeng
     * @date: 2023-02-24 10:31:50
     * @param: inputStream
     * @param: pageNum
     * @return: List<BufferedImage>
     * @modify:
     */
    private static List<BufferedImage> wordToImg(InputStream inputStream, int pageNum) throws Exception {
        try {
            Document doc = new Document(inputStream);
            ImageSaveOptions options = new ImageSaveOptions(SaveFormat.BMP);
            options.setPrettyFormat(true);
            options.setResolution(imgResolution);
            options.setUseAntiAliasing(true);
            options.setUseHighQualityRendering(true);
            int pageCount = doc.getPageCount();
            if (pageCount > pageNum) {//生成前pageCount张
                pageCount = pageNum;
            }
            List<BufferedImage> imageList = new ArrayList<BufferedImage>();
            for (int i = 0; i < pageCount; i++) {
                OutputStream output = new ByteArrayOutputStream();
                options.setPageIndex(i);

                doc.save(output, options);
                ImageInputStream imageInputStream = javax.imageio.ImageIO.createImageInputStream(parse(output));
                imageList.add(javax.imageio.ImageIO.read(imageInputStream));

            }
            return imageList;
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }

    /**
     * @description:   合并任数量的图片成一张图片
     * @author: liwanpeng
     * @date: 2023-02-24 10:33:01
     * @param: isHorizontal
     * @param: imgs
     * @return: java.awt.image.BufferedImage
     * @modify:
     */
    private static BufferedImage mergeImage(boolean isHorizontal, List<BufferedImage> imgs) throws IOException {
        // 生成新图片
        BufferedImage destImage = null;
        // 计算新图片的长和高
        int allw = 0, allh = 0, allwMax = 0, allhMax = 0;
        // 获取总长、总宽、最长、最宽
        for (int i = 0; i < imgs.size(); i++) {
            BufferedImage img = imgs.get(i);
            allw += img.getWidth();

            if (imgs.size() != i + 1) {
                allh += img.getHeight() + 5;
            } else {
                allh += img.getHeight();
            }


            if (img.getWidth() > allwMax) {
                allwMax = img.getWidth();
            }
            if (img.getHeight() > allhMax) {
                allhMax = img.getHeight();
            }
        }
        // 创建新图片
        if (isHorizontal) {
            destImage = new BufferedImage(allw, allhMax, BufferedImage.TYPE_INT_RGB);
        } else {
            destImage = new BufferedImage(allwMax, allh, BufferedImage.TYPE_INT_RGB);
        }
        Graphics2D g2 = (Graphics2D) destImage.getGraphics();
        g2.setBackground(Color.LIGHT_GRAY);
        g2.clearRect(0, 0, allw, allh);
        g2.setPaint(Color.RED);

        // 合并所有子图片到新图片
        int wx = 0, wy = 0;
        for (int i = 0; i < imgs.size(); i++) {
            BufferedImage img = imgs.get(i);
            int w1 = img.getWidth();
            int h1 = img.getHeight();
            // 从图片中读取RGB
            int[] ImageArrayOne = new int[w1 * h1];
            ImageArrayOne = img.getRGB(0, 0, w1, h1, ImageArrayOne, 0, w1); // 逐行扫描图像中各个像素的RGB到数组中
            if (isHorizontal) { // 水平方向合并
                destImage.setRGB(wx, 0, w1, h1, ImageArrayOne, 0, w1); // 设置上半部分或左半部分的RGB
            } else { // 垂直方向合并
                destImage.setRGB(0, wy, w1, h1, ImageArrayOne, 0, w1); // 设置上半部分或左半部分的RGB
            }
            wx += w1;
            wy += h1 + 5;
        }
        return destImage;
    }

    /**
     * @description: outputStream转inputStream
     * @author: liwanpeng
     * @date: 2023-02-24 10:31:05
     * @param: out
     * @return: java.io.ByteArrayInputStream
     * @modify:
     */
    private static ByteArrayInputStream parse(OutputStream out) throws Exception {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        baos = (ByteArrayOutputStream) out;
        ByteArrayInputStream swapStream = new ByteArrayInputStream(baos.toByteArray());
        return swapStream;
    }
//
	public static void main(String[] args) {
		try {
//			int i = wordToImg("1", "D:\\国网营销部关于开展2021年下半年营销设备供应商绩效评价和202 (1).docx", "D:/test", true);
//            saveImage("D:/","1677207158434_1.docx");
            File file = new File("D:/国网营销部关于开展2021年下半年营销设备供应商绩效评价和202 (1).docx");
            System.out.println(file.isFile());
            System.out.println(file.getParent());
            System.out.println(file.getParent());
        } catch (Exception e) {
			e.printStackTrace();
		}
	}
}
